


import java.util.List;

import javax.vecmath.Vector3d;




/**
 * Usually more than one Worker will be started.
 * A Worker charges a new position for a planet.
 * If he has done his job, he will get a new job or will go sleeping.
 *
 * @param 	KoeperListe,
 * 			ZentralGestin,
 * 			delta_t,
 * 			DummyObject o
 * @return 
 * @author mac_fly
 */
public class Worker implements Runnable{

								
private List<Body> 	bodyList;		// List of all Planets except the ZentralGestirn
private Body 		centralBody;		// The Planet ZentralGestirn
private int 			delta_t;			// Time between each Calculation
private DummyObject 	o;					// DummyObject given by param
private Master 			master;					// Master given by param
private int 			id;					// Position in the list

	
	
	public Worker (List<Body> bodyList, Body centralBody, int delta_t,DummyObject o, Master master)
	{
		this.bodyList = 		bodyList;
		this.centralBody = 	centralBody;
		this.delta_t = 			delta_t;
		this.o = 				o;
		this.master = 				master;
	}
	
	public void run()
	{
		while (true)
		{
			while (true)
			{
				this.id = master.getCounterJob()-1 ;			// CounterJob returns Values between 1 and PlanetListSize -1
				if(id == bodyList.size())			// If all Jobs are out, go sleeping
				{
					o.sleep();
				}
				else
				{
					break;
				}
			}
			Body currentBody = bodyList.get(id);	 			// Planet, selected by ID
			Vector3d completeA = new Vector3d();			// The entire Acceleration
			currentBody.calcAcceleration(centralBody); 	// Acceleration to the Middle (ZentralGestirn)
			completeA.add(currentBody.getAcceleration());						// Adding to the entire Acceleration the actual Acceleration
			for (Body element : bodyList) 			// aktBezugsK = actual referring Planet
				{ 
					if(element.equals(currentBody)) 			// If it is the own Planet, nothing to do
					continue;
					currentBody.calcAcceleration(element);// Calculate Acceleration to the actual referring Planet
					completeA.add(currentBody.getAcceleration()); 			// Adding actual Acceleration to the entire Acceleration
				}
			currentBody.setAcceleration(completeA);							// Updating the Acceleration of the actual Planet
			Vector3d newPos = currentBody.calcNewPos(delta_t); 	// Giving back the new Position
			currentBody.calcVelocity(delta_t);  	// Calculating new Speed 
//			System.out.println(newPos);
			currentBody.setNewPosition(newPos);					// Setting new Position
			master.setAmountAnswers();							// Let Master know you have done your Job
			if(master.getAmountAnswers() == bodyList.size())	 
				{
					lastWorker();							// Wake up Master because you are the last Worker
				}
		}	
	}
	
	private synchronized void lastWorker()					// Wakes up the Master before sleeping
	{
		synchronized (o) 
		{
		    master.masterWakeUp(); 								// Wakes up the Master
		    try 
		    {
		    	o.wait();									// And go sleeping
		    } 
		    catch (InterruptedException e) 
		    {
		    	e.printStackTrace();
		    }  
		}
	}	
}